import { isIPv4, isIPv4WithMask, isIPv6, isIPv6WithPrefix } from "./regexp";

export { parseQuasiIP };

/**
 * 对输入字符串进行解析，用逗号(,)、中文逗号()、回车(\n)，作为分隔符，拆分为多个子字符串。
 * 对每个拆分后子字符串进行 IP 格式判断，支持：
 * 1. IPv4
 * 2. IPv4掩码
 * 3. IPv6
 * 4. IPv6前缀
 * 5. IPv4 范围（1.1.1.1-1.1.1.10）
 * 6. IPv6 范围
 * 将解析后的结果以数组对象格式范围，每个对象中包含多个标记 ip 类型的属性
 *
 * @param {string} str 待解析字符串
 * @returns {Array<{}>} 解析后 IP 对象数组
 */
function parseQuasiIP(str?: string) {
  if (!str) return [];

  const ips: Array<
    | {
        type: "ip";
        value: string;
        v4: Boolean;
        v6: Boolean;
        origin: string;
        isValid: Boolean;
      }
    | {
        type: "ipMask";
        value: string;
        v4: Boolean;
        v6: Boolean;
        origin: string;
        isValid: Boolean;
      }
    | {
        type: "ipRange";
        value: [string, string];
        v4: Boolean;
        v6: Boolean;
        origin: string;
        isValid: Boolean;
      }
    | {
        type: "error";
        v4: Boolean;
        v6: Boolean;
        origin: string;
        isValid: Boolean;
      }
  > = [];

  const items = str.replaceAll(",", "\n").replaceAll("，", "\n").split("\n");

  for (const i of items) {
    const t = i.trim();
    if (t === "") continue;

    if (isIPv4(t)) {
      ips.push({
        v4: true,
        v6: false,
        origin: i,
        isValid: true,
        type: "ip",
        value: t,
      });
    } else if (isIPv4WithMask(t)) {
      ips.push({
        v4: true,
        v6: false,
        origin: i,
        isValid: true,
        type: "ipMask",
        value: t,
      });
    } else if (isIPv6(t)) {
      ips.push({
        v4: false,
        v6: true,
        origin: i,
        isValid: true,
        type: "ip",
        value: t,
      });
    } else if (isIPv6WithPrefix(t)) {
      ips.push({
        v4: false,
        v6: true,
        origin: i,
        isValid: true,
        type: "ipMask",
        value: t,
      });
    } else {
      const [a, b] = i.split("-").map((j) => j.trim());

      if (isIPv4(a) && isIPv4(b)) {
        ips.push({
          v4: true,
          v6: false,
          origin: i,
          isValid: true,
          type: "ipRange",
          value: [a, b],
        });
      } else if (isIPv6(a) && isIPv6(b)) {
        ips.push({
          v4: false,
          v6: true,
          origin: i,
          isValid: true,
          type: "ipRange",
          value: [a, b],
        });
      } else {
        ips.push({
          v4: false,
          v6: false,
          origin: i,
          isValid: false,
          type: "error",
        });
      }
    }
  }

  return ips;
}
